פרצות אבטחה נפוצות בהעלאת קבצים בעזרת PHP

Similar documents
ASP.Net MVC + Entity Framework Code First.

טכנולוגיית WPF מספקת למפתחים מודל תכנות מאוחד לחוויית בניית יישומיי

ניפוי שגיאות )Debug( מאת ישראל אברמוביץ

DNS פרק 4 ג' ברק גונן מבוסס על ספר הלימוד "רשתות מחשבים" עומר רוזנבוים 1

תצוגת LCD חיבור התצוגה לבקר. (Liquid Crystal Display) המערכת.

קשירות.s,t V שני צמתים,G=(V,E) קלט: גרף מכוון מ- s t ל- t ; אחרת.0 אם יש מסלול מכוון פלט: הערה: הגרף נתון בייצוג של רשימות סמיכות.

המחלקה למדעי המחשב, אוניברסיטת בן גוריון מבני נתונים, סמסטר אביב 2102 עבודת בית מספר - 2 מעשית

Reflection Session: Sustainability and Me

Rules Game (through lesson 30) by Nancy Decker Preparation: 1. Each rule board is immediately followed by at least three cards containing examples of

מכונת מצבים סופית תרגול מס' 4. Moshe Malka & Ben lee Volk

NTFS ADS Magic Tricks

Patents Basics. Yehuda Binder. (For copies contact:

המבנה הגאומטרי של מידה

THINKING ABOUT REST THE ORIGIN OF SHABBOS

מבוא למחשב בשפת פייתון

Hebrew Ulpan HEB Young Judaea Year Course in Israel American Jewish University College Initiative

A R E Y O U R E A L L Y A W A K E?

Privilege Escalation

FILED: NEW YORK COUNTY CLERK 07/16/2014 INDEX NO /2014 NYSCEF DOC. NO. 134 RECEIVED NYSCEF: 07/16/2014 EXHIBIT 37

דגשים: הערות: John Bryce Linux Forum: (Linux) BIND Mini How-To (In Hebrew) על שרת Red Hat Enterprise Linux גרסא.5.

Mage lvl 90 - The Magento RCE

תכנות בטוח חלק ב ' מאת עידו קנר

מבוא לתכנות ב- JAVA תרגול 7

A JEW WALKS INTO A BAR: JEWISH IDENTITY IN NOT SUCH JEWISH PLACES

מבוא לתכנות - פיתוח משחקים ב Action Script 3.0

Practical Session No. 13 Amortized Analysis, Union/Find

כפתור רדיו בחירה בודדת מתוך רשימת אפשרויות

מבוא לשפת C תירגול 1: מבוא מבוא לשפת סי - תירגול 1

Structural Vs. Nominal Typing

הקדמה בדיקת תמיכה ב- SSL מאת עידו קנר

מדריך למשתמש התקנה עצמית

מדריך למשתמש התקנה עצמית

ANNEXURE "E1-1" FORM OF IRREVOCABLE STANDBY LETTER OF CREDIT PERFORMANCE OF CONTRACT (WHERE PRICES ARE NOT LINKED TO AN ESCALATION FORMULA)

מבוא לאסמבלי מאת אופיר בק חלקים נרחבים ממאמר זה נכתבו בהשראת הספר "ארגון המחשב ושפת סף" אשר נכתב ע"י ברק גונן לתוכנית גבהים של משרד החינוך.

תרגול 8. Hash Tables

מבוא לתכנות - פיתוח משחקים ב Action Script 3.0

מבוא לשפת C מבוא לשפת סי - תירגול 1

A Long Line for a Shorter Wait at the Supermarket

זה. Nir Adar

מדריך לניהול VPS טריפל סי מחשוב ענן בע"מ.

ל"תוכנה" שכותבים, כמו פונקציה זו, קוראים "קוד"

FILED: NEW YORK COUNTY CLERK 07/16/2014 INDEX NO /2014 NYSCEF DOC. NO. 102 RECEIVED NYSCEF: 07/16/2014 EXHIBIT 5

מושגים בסיסיים תלמידים והורים יקרים,

עץ תורשה מוגדר כך:שורש או שורש ושני בנים שכל אחד מהם עץ תורשה,כך שערך השורש גדול או שווה לסכום הנכדים(נכד-הוא רק בן של בן) נתון העץ הבא:

פרוטוקול HTTP הפונקציה header שליחת מידע דחוס. עבודה עם cookies Haim Michael. All Rights Reserved.

הגדרות טלפון פוליקום בקישור הבא יש טבלה מסודרת שבה מופיעים כל סוגי הטלפון ולאיזה גירסא ניתן לשדרג

Genetic Tests for Partners of CF patients

Name Page 1 of 6. דף ט: This week s bechina starts at the two dots in the middle of

זו מערכת ישרת זוית )קרטזית( אשר בה יש לנו 2 צירים מאונכים זה לזה. באותו מישור ניתן להגדיר נקודה על ידי זוית ורדיוס וקטור

Visual C# Express יסודות מדעי המחשב 1 מהדורת עיצוב תשס"ו 2006 כתבה: יעל בילצ'יק (סופרין)

Computer Structure. Exercise #1 יש להגיש את התשובות הסופיות על גבי טופס זה.

FULL ARTICLE ACTIVE DIRECTORY

הבינגמה הדובע תביבסב תונכתל ריהמ ךירדמ

Yetzer Shalom: Inclinations of Peace

אנגלית (MODULE E) בהצלחה!

Operating Systems, 142. Practical Session 12 File Systems, part 2

מנדליי הינה תוכנה חינמית המיועדת לעזור בניהול, שיתוף, קריאה, הוספת הערות וציטוט של מאמרים. בנוסף מתפקדת גם כרשת חברתית של אנשי אקדמיה ומחקר.

מדריך למשתמש בשירות. yes MultiRoom

FULL ARTICLE ACTIVE DIRECTORY

SPSS 10.0 FOR WINDOWS

-7h3r3 15 n0 5p00n- Digital Whisper גליון 89, דצמבר 2017

1.1. הקדמה (דיסק). מדריכי. (מחיצות) Link

אתרים כיום חייבים להיות נגישים יום ולילה מכל מקום בעולם, על כן אפליקציות web שאינן בטוחות חושפות פתח להתקפות על בסיס הנתונים שמקושר לאתר.

Apple, keys, pen, pencils, pencilbox,(toy)elephant,( toy) boy, (toy) girl, ball

אנגלית שאלון ז' ג רסה א' הוראות לנבחן בהצלחה! )4( ההנחיות בשאלון זה מנוסחות בלשון זכר ומכוונות לנבחנות ולנבחנים כאחד. (MODULE G)

Chofshi.

תרגיל בית מספר - 1 להגשה עד 9 בנובמבר בשעה 23:55

מדור מערכות מידע פיננסיות

ניסוי בפייתון מכון טכנולוגי לישראל הניסוי מתקיים בבניין פישבך, חדר 573 )במסדרון למאייר(. המאחר ביותר מ- 53 דקות לא יורשה לבצע את הניסוי.

Visual C# Express Edition 2005

ראש השנה דף. 1. A) Our משנה says,... שנראה בעליל בין שלא נראה בעליל.בין Based on this,פסוק what does the word עליל mean?

נושא ה System Preparation Tool -הידוע בכינויו Sysprep

פרק 2- תכנות. socketים ברק גונן מבוסס על ספר הלימוד "רשתות מחשבים" עומר רוזנבוים 1

מבוא לרשתות - תרגול מס' 11 Transparent Bridges

אוניברסיטת בן גוריון בנגב

תכניות סטנדרטיות ב UNIX שרשור פקודות באמצעות Pipeline עבודה ב- bash

Advisor Copy. Welcome the NCSYers to your session. Feel free to try a quick icebreaker to learn their names.

שאלון ד' הוראות לנבחן

מספר מילה. you very hungry am דוגמאות: decision trees ההודעה.

מדריך שימוש בדואר האלקטרוני

מספר ת"ז: יש לסמן את התשובה הטובה ביותר בתשובון. לא יינתן ניקוד על סימון תשובה בטופס הבחינה או במחברת הבחינה.

שאלון ו' הוראות לנבחן

נספח: כישורי חשיבה )לפרק ראשון ושני( אנגלית (MODULE F) ספרות או: מילון אנגלי-ערבי / ערבי-אנגלי או: מילון אנגלי-אנגלי-ערבי

תאריך הבחינה: מבוא למדעי המחשב ד "ר פז כרמי פרופ' מייק קודיש ד "ר חן קיסר ד "ר צחי רוזן שם הקורס: מבוא למדעי המחשב מספר הקורס:


Name Page 1 of 5. ,דף ד: This week s bechina starts at the bottom of שיר של חול

מדריך המוצר של GFI מסייע ארכיו ן

חוק זכויות הסוכן חוק חוזה סוכנות )סוכן מסחרי וספק(

רזולוציה, ,DPI משה רונן ספטמבר 2007

מנגנון 5522 מידע על המנגנון מצב תצוגת שעה

הבסיס כתיבת התכנית הראשונה שימוש במשתנים. הטיפוס הבסיסי object. הטיפוס הבסיסי string משפטי בקרה. שימוש ב- Enumerations. שימוש ב- Namespaces

דיאלוג מומחז בין מרטין בובר וקרל רוג'רס

שאלות חזרה לקראת מבחן מפמ"ר אינטרנט וסייבר

א נ ג ל י ת בהצלחה! ב. משרד החינוך בגרות לנבחנים אקסטרניים )מילון הראפס אנגלי-אנגלי-ערבי( השימוש במילון אחר טעון אישור הפיקוח על הוראת האנגלית.

מספר השאלון: Thinking Skills נספח: כישורי חשיבה )לפרק ראשון ושני( א נ ג ל י ת (MODULE F) ספרות )מילון הראפס אנגלי-אנגלי-ערבי(

ב. משרד החינוך בגרות לנבחנים אקסטרניים א נ ג ל י ת (MODULE B) הוראות מיוחדות: )2( בתום הבחינה החזר את השאלון למשגיח. בהצלחה!

Name Page 1 of 5. דף ז. This week s bechina begins with the fifth wide line at the top of

IDS- Intrusion Detection System

מערכים Haim Michael. All Rights Reserved.

Summing up. Big Question: What next for me on my Israel Journey?

Transcription:

פרצות אבטחה נפוצות בהעלאת קבצים בעזרת PHP מאת Hyp3rInj3cT10n העלאת קבצים ושיתופם הוא עניין שהפך לנפוץ מאוד בימינו: לא פעם ולא פעמיים אנחנו נתקלים במצבים שבהם אנו צריכים ו/או רוצים לשתף קבצים - בין אם מדובר בתמונות, סירטונים או קבצים מסוגים אחרים שנועדו בין השאר לצפיה או להורדה. מפתחי ה- PHP יצרו עבור בונה האתר מספר פונקציות כדוגמת הפונקציה,move_uploaded_file שמעלה קבצים לשרת. הפונקציה עושה את עבודתה בצורה יפה מאוד, אך משאירה את האחריות לבדוק את הקובץ בידי המתכנת עצמו. נתמקד במאמר זה בפרצות נפוצות ואפשריות שנוצרות בעת תיכנות מערכות העלאת קבצים. לשם הנוחות, נשתמש בדוגמאות בשפת PHP אחרות. אך רב הדוגמאות שאביא מקבילות גם בשפות צד שרת אפשרויות בקובץ ההגדרות של ה- PHP לפני שנתחיל להתעסק בסקריפטים ב- PHP, אנחנו צריכים להכיר ולטפל קודם כל בסביבת העבודה שלנו: השרת. ישנן מספר הגדרות שנרצה לערוך ולוודא. ההגדרה הראשונה: בקובץ ההגדרות של PHP קיימת ההגדרה,file_uploads שקובעת האם יהיה ניתן להעלות קבצים באמצעות פרוטוקול ה- HTTP. אנחנו כמובן נוודא שאפשר להעלות קבצים באמצעות ה- HTTP, נוודא שההגדרה אכן דלוקה, כלומר: file_uploads = On upload_max_filesize קובעת את הגודל המירבי המותר לקובץ המועלה באמצעות ה- HTTP. עם זאת, אל תבנו על ההגדרה הזו לצורך אבטחת השרת שלכם - תמיד עדיף לבצע בדיקה ידנית שאותה נציג. לצורך הדוגמא נגדיר: upload_max_filesize = 10M מאחר ואנו משתמשים במתודת POST לצורך עניין העלאת קבצים יש עוד מספר דברים להגדיר. ההגדרה post_max_size מייצגת את הגודל המירבי של בקשה המשתמשת בשיטה.POST הגדרה זו משפיעה גם על העלאות קבצים באמצעות השיטה,POST ולכן יהיה כדאי להשאיר את הערך של ההגדרה הזו בדוגמא

לערך של ההגדרה upload_max_filesize או ערך הגדול ממנו כדי למנוע בעיות עם גודלו המירבי של הקובץ. בדוגמאות במסמך זה נשתמש בהגדרה הבאה: post_max_filesize = 11M max_input_time מגדירה את הזמן )בשניות( שמותר ל- PHP לחכות כדי לקבל את המידע. בעת העלאת קבצים גדולים בחיבורי אינטרנט איטיים, הזמן עלול לעבור את הערך,max_input_time ואז ההעלאה תפסק ותכשל. אפשר להגדיר את max_input_time כמספר גדול כדי למנוע מצב כזה: max_input_time = 9999 עם זאת, עדיף להשאיר הגדרה זו בערך מעשי, למשל 03 או 03 כדי למנוע ניצול משאבים גרוע. max_input_time = 60 MAX_FILE_SIZE מגדיר את גודל הקובץ המקסימלי, האומנם? להלן דוגמא שכיחה לקוד לבדיקת גודל הקובץ: <?php if ( isset($_files['file']) ) $name = $_FILES['file']['name']; $tmp = $_FILES['file']['tmp_name']; $error = $_FILES['file']['error']; if ( $error == UPLOAD_ERR_OK && move_uploaded_file($tmp, $name) ) echo 'Your file has been uploaded.'; echo 'An error has been occurred, file not uploaded.'; echo '<br /><br />'; echo <<<END File: <input type="file" name="file" /> <input type="hidden" name="max_file_size" value="100000" /> <input type="submit" value="upload" /> </form> END;?> 0

הגדרנו בעזרת MAX_FILE_SIZE את גודל הקובץ המקסימלי ל- 033 אלף בייטים. אם גודל הקובץ יעלה על הגודל שצויין תוחזר שגיאה והתהליך יפסק. בפתרון זה יש בעיה גדולה: MAX_FILE_SIZE מוגדר בצד הלקוח. כלומר, הוא ניתן לשינוי. אפשר לשנות את MAX_FILE_SIZE באמצעות Injection, Javascript Form Manipulation ודרכים רבות נוספות. דוגמא ל- Manipulation Form להלן הטופס שלנו: File: <input type="file" name="file" /> <input type="hidden" name="max_file_size" value="100000" /> <input type="submit" value="upload" /> </form> כפי שניתן לראות בבירור, MAX_FILE_SIZE מוגדר בטופס שלנו כ- 033,333 בתוך שדה input מוסתר Firefox האפשרות הפשוטה ביותר היא להשתמש באחת מתוך אלפי התוספות של הדפדפן.)hidden( בשביל לשנות את סוג ה- input שנבחר, בהתאם למה שנרצה להעלות. ממוסתר לטקסט,)text( כדי שנוכל לשנות את ה- 033,333 לכל ערך אפשרות שניה שחשוב להכירה היא השיטה הידנית - שיכתוב הקוד ללא כלים: נעתיק את הקוד ונשנה את שדה ה- hidden ל- text, )נוכל גם לשנות את ערך ברירת המחדל אם נרצה(. בסיום העריכה נשמור את הקובץ כ- HTML. הקוד שלנו צריך להראות כך: File: <input type="file" name="file" /> <input type="text" name="max_file_size" value="5000000" /> <input type="submit" value="upload" /> </form> כדי שהדוגמא תעבוד יש לעדכן את כתובת הטופס )דבר שאנשים נוטים לשכוח(. נחזור שוב לשורה הראשונה: הסימן "?" )סימן שאלה( מייצג למעשה את שורת הכתובת, והמשתנים שבאים לאחריה. זוהי דרך קצרה מאוד להפנות את הקובץ לעצמו, במקום להשתמש במשתנים ולהסתבך בחיפוש שם וכתובת הקובץ. כדי שהטופס יעבוד נשנה את הערך של ה- action לכתובת של הקובץ המעלה את הקבצים, לדוגמא: <form action="http://example.com/upload.php" method="post" enctype="multipart/form-data"> 3

שימו לב שבמידה ויש מידע המקשר אל עמוד ההעלאה והוא מועבר באמצעות שורת הכתובת יש לצרף אותו. לדוגמא: <form action="http://example.com/index.php?page=upload&terms=agreed" method="post" enctype="multipart/form-data"> דוגמא ל- Injection Javascript דרך נוספת היא שימוש בקוד Javascript כדי לשנות את הערך של.MAX_FILE_SIZE שיטה זו נקראית לעתים גם.Javascript Manipulation אנחנו משתמשים בכך שניתן לכתוב פקודות JavaScript בשורת הכתובת של הדפדפן, שיפעלו על החלון הנוכחי. נסו למשל לכתוב בדפדפן שלכם בשורת הכתובת את השורה: javascript:alert('can you see this?'); הריצו את הקוד בדפדפן שלכם, בשורת הכתובת. תקפוץ לכם הודעת Alert עם הטקסט. כעת נראה את אופן הניצול האפשרי בדוגמא שהצגנו בפרק הקודם. הפקודה הבאה תראה את הערך של :MAX_FILE_SIZE javascript:alert(document.getelementsbyname("max_file_size")[0].value); הפקודה הבאה תשנה ערך זה: javascript:document.getelementsbyname("max_file_size")[0].value=999999;return; השתמשנו ב- getelementsbyname, ובחרנו ב- 3 את ערכו של MAX_FILE_SIZE כ- 999999. צורת כתיבה נוספת: שמייצג את המופע הראשון )והיחיד(. הגדרנו מחדש javascript:void(document.getelementsbyname("max_file_size")[0].value=999944); אם לא נשתמש ב- void )או ב- return ( אנחנו נועבר לדף שאינו קיים או לדף לבן - הדפדפן רוצה להציג לנו את הפלט של הקוד שלנו. לקוד שאנחנו רוצים לבצע לא אמור להיות פלט מיוחד ואנחנו רוצים להשאר באותו הדף, ולשם כך בדיוק אנו משתמשים ב- void. פונקציה זו לא מחזירה פלט, ובעזרתה אנחנו לא נועבר לדף לא רצוי. לפני שנמשיך, נראה יתרון משמעותי נוסף שנותנת לנו הפונקציה,alert בעזרת הדוגמא הבאה: javascript:alert(document.getelementsbyname("max_file_size")[0].value); 4

לא עשינו שום דבר מיוחד - הכנסנו את הערך של MAX_FILE_SIZE יכולות להיות 2 תגובות אפשריות: לפונקצית ה- Alert. לפעולה הזאת תקפוץ הודעת Alert עם התוכן של.MAX_FILE_SIZE נוכל לראות שבאמת שינינו את ערכו. לא יקרה כלום. נסיק כי טעינו והפניה לא נכונה ו/או שהערך המוחזר הוא ריק. )יש דפדפנים שכן יציגו Alert ריק(.0.2 נמשיך לעוד דוגמא שבעזרתה נוכל לערוך את הערך ב- MAX_FILE_SIZE : javascript:void(document.getelementsbyname("max_file_size")[0].type='text'); שורה זו משנה את הסוג של ה- input מ- hidden לטקסט. כעת, ניתן לשנות את הערך שלו בטופס עצמו. התגוננות 5 כדי להתגונן נפעיל בדיקה נוספת בצד השרת לבדיקת הערך של :MAX_FILE_SIZE <?php $maxfilesize = 100000; if ( isset($_files['file']) ) $name = $_FILES['file']['name']; $tmp = $_FILES['file']['tmp_name']; $error = $_FILES['file']['error']; if ( isset($_post['max_file_size']) && $maxfilesize == $_POST['MAX_FILE_SIZE'] ) if ( $error == UPLOAD_ERR_OK && move_uploaded_file($tmp, $name) ) echo 'Your file has been uploaded.'; echo 'An error has been occurred, file not uploaded.'; echo 'Were you trying to trick us?'; echo '<br /><br />'; echo <<<END File: <input type="file" name="file" /> <input type="hidden" name="max_file_size" value="$maxfilesize" /> <input type="submit" value="upload" /> </form>

END;?> נוכל גם לכתוב פתרון שלא יתבסס כלל על :MAX_FILE_SIZE <?php if ( isset($_files['file']) ) $name = $_FILES['file']['name']; $tmp = $_FILES['file']['tmp_name']; $error = $_FILES['file']['error']; $size = $_FILES['file']['size']; if ( $size < 100000 ) if ( $error == UPLOAD_ERR_OK && move_uploaded_file($tmp, $name) ) echo 'Your file has been uploaded.'; echo 'An error has been occurred, file not uploaded.'; echo 'Were you trying to trick us?'; echo '<br /><br />'; echo <<<END File: <input type="file" name="file" /> <input type="submit" value="upload" /> </form> END;?> החלפת קובץ שמועלה בקובץ קיים מה יקרה אם נרצה להעלות תמונה בשם bg.jpg בזמן שהיא כבר קיימת על השרת? התמונה החדשה שנעלה תחליף את הישנה. מה יקרה אם תוקף יעלה קובץ שתוכנו "Hacked" בשם זהה לזה של קובץ האינדקס של המערכת? יכולים להווצר מצבים בהם קבצים חשובים באתר מוחלפים בקבצים אחרים! הגדרת מיקום הקובץ מומלץ מאוד להגדיר תיקיה נפרדת לקבצים שמועלים לשרת, כדי למנוע מצבים בהם מוחלף קובץ קיים באחר. השורה בדוגמא שמגדירה את האופן שבו ישמר הקובץ היא: כדי להכניס את הקובץ לתיקיה, פשוט נוסיף את שמה: $name = $_FILES['file']['name']; $name = 'uploads/'.$_files['file']['name']; 6

כעת, הקבצים יועלו לתיקיה.uploads הגדרת שם הקובץ הצלחנו לגרום לקבצים לא להחליף את הקבצים שבתיקייה שלנו בעזרת הפרדה שלהם לתיקיה אחרת, אך עדיין לא פתרנו את כל הבעיות. לדוגמא, מה יקרה אם נעלה קובץ בשם program.exe שסוגר פירצות אבטחה במחשב, ולאחר מכן גולש אחר יעלה וירוס קטלני בשם?program.exe הקובץ החדש יחליף את הקובץ הקיים, ויהיה קשה לנו להבחין בכך. הפתרון שלנו יהיה כמובן בעזרת שינוי שמות הקבצים. נגדיר שמות חדשים לקבצים שמועלים: ניצור לקבצים שמועלים על ידי הגולשים שמות חדשים משלנו. נדאג ששמות שניצור לקבצים שמועלים לא יוכלו לחזור על עצמו. לדוגמא, פתרון אפשרי יכול להיות: $name = 'uploads/'.time().crc32($_files['file']['name'].time()).'- '.$_FILES['file']['name']; הוספנו לשם הקובץ מקדם שסביר להניח שלא יוכל לחזור על עצמו, מאחר והוא מתבסס על שני מרכיבים דינאמיים מאוד: שם הקובץ והזמן הנוכחי. ההסתברות ששני קבצים עם שם זהה יועלו במקביל היא אפסית. סיומות קבצים הגנה נוספת היא להגביל את סוג הקבצים שניתן להעלות לשרת )סוג הקבצים - על פי הסיומת שלהם(. בדרך כלל אנשים נוטים להגדיר סיומות אסורות Filter(,)Black List ולא אילו סיומות מותרות ( List White.)Filter למרות שזו גישה מאוד אינטואיטיבית, היא אינה נכונה ברוב המקרים - נראה זאת כעת. להלן דוגמת קוד לבדיקת סיומות אסורות: <?php $maxfilesize = 100000; $exts = array('php','cgi','html'); if ( isset($_files['file']) ) $name = 'uploads/'.time().crc32($_files['file']['name'].time()).'- '.$_FILES['file']['name']; $tmp = $_FILES['file']['tmp_name']; $error = $_FILES['file']['error']; if ( isset($_post['max_file_size']) && $maxfilesize == $_POST['MAX_FILE_SIZE'] ) $extension = pathinfo($tmp); $extension = strtolower($extension['extension']); 7

if ( in_array($ext,$exts) ) echo 'Bad extension'; if ( $error == UPLOAD_ERR_OK && move_uploaded_file($tmp, $name) ) echo 'Your file has been uploaded.'; echo 'An error has been occurred, file not uploaded.'; echo 'Were you trying to trick us?'; echo '<br /><br />'; $extstext = implode(', ',$exts); echo <<<END File: <input type="file" name="file" /> <input type="hidden" name="max_file_size" value=" $maxfilesize" /> <input type="submit" value="upload" /><br /> Disabled Extensions: $extstext. </form> END;?> אנחנו מקבלים רשימה של סיומות קבצים אסורות. אם המערכת מזהה סיומת מסוכנת, תהליך ההעלאת הקובץ מבוטל. נעבור כעת על מספר דוגמאות לדרכי ניצול פוטנציאליות במערכות הבנויות באופן זה או דומה. הרצת קוד בצד השרת )למשל )PHP בדוגמא אמנם הסיומת php חסומה, אך עדיין עומדות לרשותינו עוד הרבה סיומות שגם הן מריצות קודים ב- PHP, למשל:.php3, php4, php5, php6, phtml יש לא מעט אנשים שמעולם לא נתקלו בסיומות האלה ולכן לא יחסמו אותן כאשר הם ישבו לכתוב את הפילטר שהצגנו קודם לכן. בנוסף שימו לב שיש אפשרות לנסות להריץ קבצי perl ו- shtml אם השרת תומך בכך. 8

הרצת קודים עם שפות צד לקוח הסיומת html אומנם חסומה לנו, אך בכל זאת נוכל לנסות להריץ קודים ב- HTML על ידי שימוש בסיומת Javascript, Flash, Java גם לנסות להפעיל ולהריץ נוכל מאחר ואנו יכולים להריץ קודים ב- HTML,.htm VBScript ועוד... ו- htpasswd htaccess קבצי htaccess ו- htpasswd וענייני אבטחה הקשורים בהם מופיעים במאמר מאת אפיק בגליון זה. קבצים אלו נשמרים בשמות:.htpasswd,.htaccess שימו לב - שמם של הקבצים הוא בעצם סיומת בלבד! בעלי אתרים רבים מכירים את הסיומות האלה, אבל הם לא חושבים עליהם כשהם חוסמים סיומות קבצים. כדי לספק לכם המחשה לסכנה, בואו נראה מספר דוגמאות מסוכנות לפעולות הניתנות לביצוע בעזרת קובץ ה- htaccess : חסימת הכניסה לתיקיה: )כך אף אחד לא יכול להכנס לתיקיה בעזרת דפדפן האינטרנט( שינוי שם קובץ האינדקס לקובץ שלנו: )בהנחה שהעלנו קובץ הנקרא )deface.html deny from all DirectoryIndex deface.html הפניית הגולש מקובץ האינדקס לקובץ מרוחק: Redirect index.php http://my-site.com/deface.html AuthName "Please Identify" AuthType Basic AuthUserFile.htpasswd Require valid-user סגירת התיקיה בסיסמה: קוד זה יקפיץ חלון המבקש שם משתמש וסיסמה, כאשר הכותרת תהיה.Please Identify במקרה הזה נצטרך גם להשתמש ב- htpasswd. קובץ זה יכיל שמות משתמשים וסיסמאות, לדוגמא: username:encrypted-password username:encrypted-password username:encrypted-password 9

שם המשתמש מופרד מהסיסמה המוצפנת בעזרת התו : )נקודתיים(, וכל שורה מפרידה בין המשתמשים האחרים. על אופן הצפנת הסיסמה הרחבנו במאמר אחר בגליון זה. בנוסף יש מספיק כלים באינטרנט לטיפול בעניין, כמו: http://tools.dynamicdrive.com/password/ התגוננות נגדיר רשימה של סיומות מותרות, במקום רשימה של סיומות אסורות: <?php $maxfilesize = 100000; $exts = array('jpg','bmp','png','gif','txt','rar','doc','ppt'); //etc... if ( isset($_files['file']) ) $name = 'uploads/'.time().crc32($_files['file']['name'].time()).'- '.$_FILES['file']['name']; $tmp = $_FILES['file']['tmp_name']; $error = $_FILES['file']['error']; if ( isset($_post['max_file_size']) && $maxfilesize == $_POST['MAX_FILE_SIZE'] ) $extension = pathinfo($tmp); $extension = strtolower($extension['extension']); if (!in_array($ext,$exts) ) echo 'Bad extension'; if ( $error == UPLOAD_ERR_OK && move_uploaded_file($tmp, $name) ) echo 'Your file has been uploaded.'; echo 'An error has been occurred, file not uploaded.'; echo 'Were you trying to trick us?'; echo '<br /><br />'; $extstext = implode(', ',$exts); echo <<<END File: <input type="file" name="file" /> <input type="hidden" name="max_file_size" value=" $maxfilesize" /> <input type="submit" value="upload" /><br /> Allowed Extensions: $extstext. </form> END;?> 02

Null Byte Poisoning ה- Byte Null הוא התו הראשון בטבלת ה- ASCII, ובדרך כלל המערכת נעזרת בו בכדי לזיהות מחרוזות. ב- HEX התו מיוצג כ- 00 )או %00( וב- PHP : ה- Byte Null הוא תו בלתי נראה. לא ניתן לראות אותו. chr(0) )Null Byte גם כ- Attack )מוכר Null Byte Poisoning לצורך ההסבר, נגיד שהתו & )אמפטסנד( יהיה ה- Byte,Null כדי שאוכל להעביר בצורה טובה יותר את ההדגמה. דמיינו לכם מערכת הכוללת פונקציה להעלאת קבצים כמו זו שנמצאת בדוגמת הקוד האחרונה עם הסיומות. כעת בואו נראה מה למשל יקרה אם שם הקובץ שנכניס יהיה השם הבא: image.jpg&.php בבדיקה שנעשה בעזרת ה- PHP, הביטוי שיבדק יהיה אך ורק: image.jpg והבדיקה תעבור בהצלחה. כאשר הקובץ יווצר, ה- Byte Null יצונזר ושם הקובץ יהיה: image.jpg.php התגוננות לכאורה נראה כי מדובר בשיטה שלא ניתנת לעצירה, אך זה לא נכון. כדי להתגונן יש להבריח או לצנזר את ה- Byte Null כך שלא יוכל לתפקד. נוכל לצנזר את ה- Byte Null בעזרת השורה הבאה: $name = str_replace(chr(0),'',$_files['file']['name']); ה- Quotes Magic מבצעים הברחה אוטומטית ל- Byte,Null אך כמובן שלא באמת נסמוך עליהם. Local File Disclosure בכל הדוגמאות עד כה שהצגנו, הצגנו הודעה אם הקובץ הועלה או שהתרחשה שגיאה והוא לא הועלה. לדוגמאות זה היה נחמד מאוד, אבל כשאנחנו מדברים על מערכת אמיתית, אנחנו נספק למשתמש קישור להורדת הקובץ. אין בעיה לתת קישור כזה - הרי יש לנו את המשתנה name שמכיל את שם הקובץ, ונוכל להשתמש בו כהפניה. צריך ליצור קובץ שיודיע לדפדפן להוריד את הקובץ, לדוגמא: <?php if ( isset($_get['file']) && is_string($_get['file']) ) if ( @file_exists($_get['file']) && @is_readable($_get['file']) ) header("content-type: application/octet-stream"); 00

header('content-disposition: attachment; filename="'.$_get['file'].'"'); readfile('uploads/'.$_get['file']);?> שורת הכתובת צריכה להיות כזאת: )כאשר filename מייצג את שם הקובץ שנרצה להוריד(?file=[filename] Path Traversal השיטה Path Traversal )מוכרת גם כ- Traversal )Directory משמשת אותנו ל"חציית" התיקיה בה אנו נמצאים. יש 2 סימונים מוכרים שיש להכיר:. )נקודה אחת( - מייצגת את התיקיה הנוכחית.. )שתי נקודות( - מייצגות תיקייה אחת למעלה. Directory( )Parent מה אם נשתמש ב- Traversal Path כדי לעלות תיקיה למעלה??file=../index.php מה שיקרה זה: readfile('uploads/../index.php'); כלומר, ניגש לתיקיה uploads ואז לתיקיה מעליה )חזרנו אחורה(, ומשם נקרא את הקובץ שנקרא.index.php המשמעות היא שכעת נוכל להוריד ולקרוא כל קובץ שנרצה מהאתר. בתוך קובץ האינדקס נוכל למצוא בדרך כלל פקודות ייבוא לקבצי תצורה אחרים, שגם אותם נוכל להוריד למחשב ולקרוא. לדוגמא, אפשר למצוא בדרך כלל בקבצי האינדקס של המערכת שמות/מיקום של קבצי הקונפיגורציה הכוללים מידע שימושי רב, כמו למשל את פרטי ההתחברות למסד הנתונים ( Connection )String המשמש את המערכת באיכסון המידע, קריאות לקבצי קונפיגורציה התומכים במערכת וכו'. אם זה לא מספיק, תמיד אפשר לחפש אחר קבצי htaccess, htpasswd ועוד קבצים שאין גישה אליהם דרך המערכת. 00

התגוננות ההתגוננות היא פשוטה מאוד: נצנזר את התווים.. )שתי נקודות( ו-/ )סלאש(. לדוגמא: $file = $_GET['file']; $file = str_replace('/','',$file); $file = str_replace('..','',$file); יש צורך להחליף אף את התווים הנ"ל בסוגי הקידודים השונים הנתמכים ע"י טכנולוגיית המערכת. File Download Injection <?php if ( isset($_get['file']) && is_string($_get['file']) ) $file = $_GET['file']; $file = str_replace(chr(0),'',$file); $file = str_replace('..','',$file); header("content-type: application/octet-stream"); header('content-disposition: attachment; filename="'.$file.'"'); readfile('uploads/'.$file);?> HTTP/1.1 200 OK Date:... Content-Type: application/octet-stream Content-Disposition: attachment; filename=[file name] Content-Length: [file length] [file content] להלן הדוגמא שבה נשתמש: התגובה שנקבל מהשרת כשניגש לקובץ תהיה בערך כזאת: כשנגש לקובץ בצורה הבאה:?file=roy.bat%0a%0dContent-Length%3A%2016%0a%0d%0a%0dshutdown%20-s%20-t%2060 CRLF = a%0d )ירידת שורה( = A%0 : )נקודתיים( = %23 רווח כלומר: roy.bat Content-Length: 16 03

shutdown -s -t 60 נקבל: HTTP/1.1 200 OK Date: [...] Content-Type: application/octet-stream Content-Disposition: attachment; filename=roy.bat Content-Length: 16 shutdown -s -t 60 Content-Length: [...] הדפדפן יתייחס לכותר ה- Content-Length הראשון שישלח לו מהשרת, ולכן יקרא רק את 00 הראשונים. למעשה, הדפדפן יוריד קובץ שנקרא roy.bat ותוכנו: התווים shutdown -s -t 60 הקובץ הוא קובץ אצווה וברגע שהגולש יפתח את אותו, תופיע לו הודעה שמחשבו ייכבה בעוד 03 שניות. אתם מוזמנים להפעיל את זה כדי לבדוק. לביטול הפעולה יש להריץ בשורת ההפעלה או ב- cmd את זה: shutdown -a במקרה הזה השתמשתי דווא בקובץ אצווה,)batch( אך כמובן שנוכל להשתמש במגוון רחב של קבצים. התגוננות נוודא כי הקובץ אכן קיים וניתן לקריאה לפני שניתן אותו לגולש. לדוגמא: <?php if ( isset($_get['file']) && is_string($_get['file']) ) $file = $_GET['file']; $file = str_replace('/','',$file); $file = str_replace('..','',$file);?> if ( @is_readable($_get['file']) ) header("content-type: application/octet-stream"); header('content-disposition: attachment; filename="'.$file.'"'); readfile('uploads/'.$file); 04

עקיפת מכסת הקבצים שניתן להעלות במקביל )לביצוע )DoS לפעמים נרצה לאפשר העלאה של יותר מקובץ אחד במקביל, למשל 5 קבצים. כך יראה הטופס: File #1: <input type="file" name="file1" /><br /> File #2: <input type="file" name="file2" /><br /> File #3: <input type="file" name="file3" /><br /> File #4: <input type="file" name="file4" /><br /> File #5: <input type="file" name="file5" /><br />... לשם ביצוע ההתקפה יש לנו מספר אפשרויות: בניית פונקציה שמתעסקת בהעלאת הקובץ, ונזמן אותה 5 פעמים. העתקת הקוד והדבקתו עוד 4 פעמים, כשבכל פעם נשנה את שם המשתנה שאיתו עובדים. להשתמש בלולאת.foreach הפיתרון השלישי הוא הנפוץ ביותר כיום והוא גם הפתרון הנוח ביותר לשימוש, אך הוא גם הפתרון הלוקה.0.2.0 בחסר. 05 דוגמא לקוד המבצע את הפיתרון השלישי: foreach ( $_FILES as $file ) $name = 'uploads/'.time().crc32($file['name'].time()).'-'.$file['name']; $tmp = $file['tmp_name']; $error = $file['error']; if ( isset($_post['max_file_size']) && $maxfilesize == $_POST['MAX_FILE_SIZE'] ) $extension = pathinfo($tmp); $extension = strtolower($extension['extension']); if (!in_array($ext,$exts) ) echo 'Bad extension'; if ( $error == UPLOAD_ERR_OK && move_uploaded_file($tmp, $name) ) echo 'Your file has been uploaded.'; echo 'An error has been occurred, file not uploaded.'; echo 'Were you trying to trick us?'; echo '<br /><br />'; הפיתרונות הראשון והשני הם סטאטים, ומיועדים להעלות רק עד חמישה קבצים בכל מילוי טופס שמתבצע, ולא יותר. לעומתם, הפיתרון השלישי יכול להעלות כמות משתנה של קבצים- כמספר הקבצים שהוא מקבל. לכן, אופן הניצול יהיה - Form Manipulation נערוך את הטופס ונשמור בקובץ חדש: )לא לשכוח את ה- action!(

<form action="[file-url]" method="post" enctype="multipart/form-data"> File #1: <input type="file" name="file1" /><br /> File #2: <input type="file" name="file2" /><br /> File #3: <input type="file" name="file3" /><br /> File #4: <input type="file" name="file4" /><br /> File #5: <input type="file" name="file5" /><br /> File #6: <input type="file" name="file6" /><br /> File #7: <input type="file" name="file7" /><br /> File #8: <input type="file" name="file8" /><br /> File #9: <input type="file" name="file9" /><br /> File #10: <input type="file" name="file10" /><br />... התגוננות לפתירת הבעיה קיימות מספר אפשרויות, אך מספיק להציג שתיים הן: שבירת הלולאה וביטול הלולאה. foreach ($_FILES as $key => $array) if ( $key == 4 ) // 0,1,2,3,4 = 5 break; if ( count($_files) <= 5 ) foreach ($_FILES as $array) דוגמא ראשונה - שבירת הלולאה: דוגמא שניה - ביטול הלולאה: סיכום במאמר זה נגעתי במספר נרחב של נקודות המופיעות בהרבה מנגנוני העלאת קבצים במערכות השונות. חשוב לזכור שבכל מערכת ומערכת יכולים להווצר סוגים שונים של חורים, אך אחד העקרונות החשובים ביותר כשמדובר בפיתוח במערכות המקבלות קלט )כל קלט שהוא( מהמשתמש הוא שלעולם אין לסמוך על המשתמש ותמיד יש לבצע בדיקות מקיפות ולוודא שאכן הקלט עומד בסטנדרטים שקבענו. 06